Java ConcurrentMap
part 9/19 · 30.6 KB total
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
* Synchronization on individual iterations is not possible.
*/
...
}
} finally {
readLock.unlock();
}
Convoys
Mutual exclusion has a lock convoy problem, in which threads may pile up on a lock, causing the JVM to need to maintain expensive queues of waiters and to 'park' the waiting Threads. It is expensive to park and unpark a Threads, and a slow context switch may occur. Context switches require from microseconds to milliseconds, while the Map's own basic operations normally take nanoseconds. Performance can drop to a small fraction of a single Thread's throughput as contention increases. When there is no or little contention for the lock, there is little performance impact; however, except for the lock's contention test. Modern JVMs will inline most of the lock code, reducing it to only a few instructions, keeping the no-contention case very fast. Reentrant techniques like native synchronization or java.util.concurrent.ReentrantReadWriteLock however have extra performance-reducing baggage in the maintenance of the reentrancy depth, affecting the no-contention case as well. The Convoy problem seems to be easing with modern JVMs, but it can be hidden by slow context switching: in this case, latency will increase, but throughput will continue to be acceptable. With hundreds of Threads , a context switch time of 10ms produces a latency in seconds.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────